import json
from django.shortcuts import render
from django.db import transaction
from valar.classes.valar_response import ValarResponse
from valar.dao import Dao
from calculater.models.bio_jet_fuel import ProductionBatch, EmissionFactors, CalculationLog
from calculater.models.lubricating_grease import LubricatingGreaseBatch


def test_request(request):
    """原有的简单计算测试接口"""
    body = json.loads(request.body)
    _id = body.get('panel_id')
    dao = Dao('calculater.InputPanel')
    panel = dao.find_one(_id)
    values = panel.inputmaterial_set.all().values("category","value")
    total = sum([v['value'] for v in values])

    r_dao = Dao('calculater.Result')
    r_dao.save_one({
        "panel_id": _id, "value": total
    })
    return ValarResponse(True)


def calculate_bio_jet_fuel_emissions(request):
    """生物航空煤油碳足迹计算接口"""
    try:
        body = json.loads(request.body)
        batch_id = body.get('batch_id')
        print("Got id: ",batch_id)
        if not batch_id:
            return ValarResponse(False, message="缺少批次ID")
        
        # 获取生产批次数据
        try:
            batch = ProductionBatch.objects.get(id=batch_id)
        except ProductionBatch.DoesNotExist:
            return ValarResponse(False, message="批次不存在")

        # 执行计算
        result = _calculate_carbon_emissions(batch)
        
        if result['success']:
            return ValarResponse(True)
        else:
            return ValarResponse(False, message=result['error'])
            
    except Exception as e:
        return ValarResponse(False, message=f"计算失败: {str(e)}")


def create_production_batch(request):
    """创建新的生产批次"""
    try:
        body = json.loads(request.body)
        
        # 创建新的生产批次
        batch = ProductionBatch.objects.create(
            batch_name=body.get('batch_name', ''),
            start_date=body.get('start_date'),
            end_date=body.get('end_date'),
            production_load=body.get('production_load', 0),
            restaurant_waste_oil_mass_t=body.get('restaurant_waste_oil_mass_t', 0),
            dmds_mass_t=body.get('dmds_mass_t', 0),
            new_hydrogen_mass_t=body.get('new_hydrogen_mass_t', 0),
            recycled_hydrogen_mass_t=body.get('recycled_hydrogen_mass_t', 0),
            nitrogen_mass_t=body.get('nitrogen_mass_t', 0),
            recycled_bio_jet_fuel_mass_t=body.get('recycled_bio_jet_fuel_mass_t', 0),
            working_hours=body.get('working_hours', 0),
            bio_jet_fuel_mass_t=body.get('bio_jet_fuel_mass_t', 0),
            bio_naphtha_mass_t=body.get('bio_naphtha_mass_t', 0),
            tail_gas_mass_t=body.get('tail_gas_mass_t', 0),
            h2o_mass_t=body.get('h2o_mass_t', 0),
            light_contaminated_oil_mass_t=body.get('light_contaminated_oil_mass_t', 0),
            recycled_water_mass_t=body.get('recycled_water_mass_t', 0),
            demineralized_water_mass_t=body.get('demineralized_water_mass_t', 0),
            condensate_mass_t=body.get('condensate_mass_t', 0),
            electricity_kwh=body.get('electricity_kwh', 0),
            steam_mass_t=body.get('steam_mass_t', 0),
            fuel_gas_mass_t=body.get('fuel_gas_mass_t', 0),
        )
        
        return ValarResponse(True)
        
    except Exception as e:
        return ValarResponse(False, message=f"创建批次失败: {str(e)}")


def _safe_float(value):
    """安全地将值转换为float，None值转换为0"""
    return float(value) if value is not None else 0.0


def _calculate_carbon_emissions(batch):
    """核心碳足迹计算函数"""
    try:
        with transaction.atomic():
            # 0. 计算工作持续时间（根据开始日期和结束日期的差值，每天24小时）
            working_days = None
            if batch.start_date and batch.end_date:
                # 计算日期差值
                date_diff = batch.end_date - batch.start_date
                working_days = date_diff.days + 1  # 包含开始和结束日期
                # 每天24小时
                calculated_working_hours = working_days * 24
                batch.working_hours = calculated_working_hours
            else:
                # 如果没有日期，使用用户输入的工作时间或默认为0
                calculated_working_hours = _safe_float(batch.working_hours)
            
            # 1. 计算生物柴油循环量（根据公式：4吨/小时 × 工作持续时间）
            calculated_recycled_bio_jet_fuel = 4.0 * calculated_working_hours
            batch.recycled_bio_jet_fuel_mass_t = calculated_recycled_bio_jet_fuel
            
            # 1. 质量平衡校验
            mass_balance_result = _validate_mass_balance(batch)
            if not mass_balance_result['valid']:
                return {
                    'success': False,
                    'error': f"质量平衡校验失败: {mass_balance_result['error']}"
                }
            
            # 2. 获取排放因子
            emission_factors = _get_emission_factors()
            if not emission_factors['success']:
                return {
                    'success': False,
                    'error': f"获取排放因子失败: {emission_factors['error']}"
                }
            
            factors = emission_factors['data']
            
            # 3. 计算原料带入排放 (E_raw)
            e_raw_kg = _safe_float(batch.new_hydrogen_mass_t) * factors['new_hydrogen_emission_factor']
            batch.e_raw_kg = e_raw_kg
            
            # 4. 计算辅助材料带入排放 (E_aux)
            e_aux_kg = (_safe_float(batch.new_hydrogen_mass_t) + _safe_float(batch.recycled_hydrogen_mass_t)) * factors['new_hydrogen_emission_factor']
            batch.e_aux_kg = e_aux_kg
            
            # 5. 计算能耗排放 (E_energy)
            energy_emissions_sum = (
                _safe_float(batch.recycled_water_mass_t) * factors['recycled_water_ef'] +
                _safe_float(batch.demineralized_water_mass_t) * factors['demineralized_water_ef'] +
                _safe_float(batch.condensate_mass_t) * factors['condensate_ef'] +
                _safe_float(batch.electricity_kwh) * factors['electricity_ef'] +
                _safe_float(batch.steam_mass_t) * factors['steam_ef'] +
                _safe_float(batch.fuel_gas_mass_t) * factors['fuel_gas_ef']
            )
            e_energy_kg = energy_emissions_sum * _safe_float(batch.production_load)
            batch.e_energy_kg = e_energy_kg
            
            # 6. 计算总排放 (E_total)
            e_total_kg = e_raw_kg + e_energy_kg + e_aux_kg
            batch.e_total_kg = e_total_kg
            
            # 7. 计算碳足迹
            total_output_mass_t = (
                _safe_float(batch.bio_jet_fuel_mass_t) + 
                _safe_float(batch.bio_naphtha_mass_t) + 
                _safe_float(batch.tail_gas_mass_t) + 
                _safe_float(batch.h2o_mass_t) + 
                _safe_float(batch.light_contaminated_oil_mass_t) + 
                _safe_float(batch.recycled_bio_jet_fuel_mass_t)
            )
            
            if total_output_mass_t > 0:
                carbon_footprint_kg_per_t = e_total_kg / total_output_mass_t
                batch.carbon_footprint_kg_per_t = carbon_footprint_kg_per_t
            else:
                batch.carbon_footprint_kg_per_t = 0
            
            # 8. 更新质量平衡数据
            batch.input_total_mass = mass_balance_result['input_total']
            batch.output_total_mass = mass_balance_result['output_total']
            batch.mass_balance_error = mass_balance_result['error']
            
            # 9. 保存计算结果
            batch.save()
            
            return {
                'success': True,
                'data': {
                    'e_raw_kg': e_raw_kg,
                    'e_energy_kg': e_energy_kg,
                    'e_aux_kg': e_aux_kg,
                    'e_total_kg': e_total_kg,
                    'carbon_footprint_kg_per_t': batch.carbon_footprint_kg_per_t,
                    'input_total_mass': batch.input_total_mass,
                    'output_total_mass': batch.output_total_mass,
                    'mass_balance_error': batch.mass_balance_error,
                    'total_output_mass_t': total_output_mass_t,
                    'calculated_recycled_bio_jet_fuel': calculated_recycled_bio_jet_fuel,
                    'calculated_working_hours': calculated_working_hours,
                    'working_days': working_days if batch.start_date and batch.end_date else None
                }
            }
            
    except Exception as e:
        return {
            'success': False,
            'error': f"计算过程中发生错误: {str(e)}"
        }


def _validate_mass_balance(batch):
    """质量平衡校验"""
    try:
        # 计算入方总量
        input_total_mass = (
            _safe_float(batch.restaurant_waste_oil_mass_t) +
            _safe_float(batch.new_hydrogen_mass_t) +
            _safe_float(batch.recycled_hydrogen_mass_t) +
            _safe_float(batch.dmds_mass_t) +
            _safe_float(batch.recycled_bio_jet_fuel_mass_t)
        )
        
        # 计算出方总量
        output_total_mass = (
            _safe_float(batch.bio_jet_fuel_mass_t) +
            _safe_float(batch.bio_naphtha_mass_t) +
            _safe_float(batch.tail_gas_mass_t) +
            _safe_float(batch.h2o_mass_t) +
            _safe_float(batch.light_contaminated_oil_mass_t) +
            _safe_float(batch.recycled_bio_jet_fuel_mass_t)
        )
        
        # 计算误差
        mass_balance_error = abs(input_total_mass - output_total_mass)
        
        # 允许误差范围（吨）
        tolerance = 0.01
        
        if mass_balance_error <= tolerance:
            return {
                'valid': True,
                'input_total': input_total_mass,
                'output_total': output_total_mass,
                'error': mass_balance_error
            }
        else:
            return {
                'valid': False,
                'error': f"质量不平衡，误差: {mass_balance_error:.4f}吨，入方: {input_total_mass:.4f}吨，出方: {output_total_mass:.4f}吨"
            }
            
    except Exception as e:
        return {
            'valid': False,
            'error': f"质量平衡校验失败: {str(e)}"
        }


def _get_emission_factors():
    """获取排放因子"""
    try:
        # 默认排放因子值
        default_factors = {
            'new_hydrogen_emission_factor': 374.0,  # kgCO2/t
            'water_emission_factor': 0.62,  # kgCO2/t
            'recycled_water_ef': 0.3,  # kgCO2/t
            'demineralized_water_ef': 6.86,  # kgCO2/t
            'condensate_ef': 10.89,  # kgCO2/t
            'electricity_ef': 0.8046,  # kgCO2/kWh
            'steam_ef': 226.82,  # kgCO2/t
            'fuel_gas_ef': 2649.48,  # kgCO2/t
        }
        
        return {
            'success': True,
            'data': default_factors
        }
            
    except Exception as e:
        return {
            'success': False,
            'error': f"获取排放因子失败: {str(e)}"
        }


# ==================== 润滑脂碳足迹计算器 ====================

def create_lubricating_grease_batch(request):
    """创建新的润滑脂生产批次"""
    try:
        body = json.loads(request.body)
        
        # 创建新的润滑脂生产批次
        batch = LubricatingGreaseBatch.objects.create(
            batch_name=body.get('batch_name', ''),
            product_mass_kg=body.get('product_mass_kg', 0),
            
            # 表1：原料投入量
            calcium_petroleum_sulfonate_kg=body.get('calcium_petroleum_sulfonate_kg', 0),
            neutral_oil_kg=body.get('neutral_oil_kg', 0),
            calcium_hydroxide_kg=body.get('calcium_hydroxide_kg', 0),
            boric_acid_kg=body.get('boric_acid_kg', 0),
            hydroxy_stearic_acid_kg=body.get('hydroxy_stearic_acid_kg', 0),
            acetic_acid_kg=body.get('acetic_acid_kg', 0),
            ga_034_kg=body.get('ga_034_kg', 0),
            
            # 表2：能耗消耗量
            natural_gas_m3=body.get('natural_gas_m3', 0),
            electricity_kwh=body.get('electricity_kwh', 0),
            steam_t=body.get('steam_t', 0),
            
            # 辅助材料（水）消耗量
            water_kg=body.get('water_kg', 0),
            
            # 表3 & 表8：详细运输数据
            # 厂外原料运输
            calcium_petroleum_sulfonate_transport_km=body.get('calcium_petroleum_sulfonate_transport_km', 0),
            calcium_petroleum_sulfonate_transport_emission_kgCO2=body.get('calcium_petroleum_sulfonate_transport_emission_kgCO2'),
            
            neutral_oil_transport_km=body.get('neutral_oil_transport_km', 0),
            neutral_oil_transport_emission_kgCO2=body.get('neutral_oil_transport_emission_kgCO2'),
            
            calcium_hydroxide_transport_km=body.get('calcium_hydroxide_transport_km', 0),
            calcium_hydroxide_transport_emission_kgCO2=body.get('calcium_hydroxide_transport_emission_kgCO2'),
            
            boric_acid_transport_km=body.get('boric_acid_transport_km', 0),
            boric_acid_transport_emission_kgCO2=body.get('boric_acid_transport_emission_kgCO2'),
            
            hydroxy_stearic_acid_transport_km=body.get('hydroxy_stearic_acid_transport_km', 0),
            hydroxy_stearic_acid_transport_emission_kgCO2=body.get('hydroxy_stearic_acid_transport_emission_kgCO2'),
            
            acetic_acid_transport_km=body.get('acetic_acid_transport_km', 0),
            acetic_acid_transport_emission_kgCO2=body.get('acetic_acid_transport_emission_kgCO2'),
            
            ga_034_transport_km=body.get('ga_034_transport_km', 0),
            ga_034_transport_emission_kgCO2=body.get('ga_034_transport_emission_kgCO2'),
            
            # 厂内运输
            internal_transport_emission_kgCO2=body.get('internal_transport_emission_kgCO2'),
            
            # 厂外产品运输
            external_product_transport_km=body.get('external_product_transport_km', 0),
            external_product_transport_emission_kgCO2=body.get('external_product_transport_emission_kgCO2'),
        )
        
        return ValarResponse(True, data={'batch_id': batch.id})
        
    except Exception as e:
        return ValarResponse(False, message=f"创建批次失败: {str(e)}")


def calculate_lubricating_grease_emissions(request):
    """润滑脂碳足迹计算接口"""
    try:
        body = json.loads(request.body)
        batch_id = body.get('batch_id')
        
        if not batch_id:
            return ValarResponse(False, message="缺少批次ID")
        
        # 获取生产批次数据
        try:
            batch = LubricatingGreaseBatch.objects.get(id=batch_id)
        except LubricatingGreaseBatch.DoesNotExist:
            return ValarResponse(False, message="批次不存在")

        # 执行计算
        result = _calculate_lubricating_grease_carbon_emissions(batch)
        
        if result['success']:
            return ValarResponse(True)
        else:
            return ValarResponse(False, message=result['error'])
            
    except Exception as e:
        return ValarResponse(False, message=f"计算失败: {str(e)}")


def _calculate_lubricating_grease_carbon_emissions(batch):
    """润滑脂核心碳足迹计算函数 - 按照复合磺酸钙润滑脂碳足迹计算方法"""
    try:
        with transaction.atomic():
            # 1. 获取排放因子
            emission_factors = _get_lubricating_grease_emission_factors()
            if not emission_factors['success']:
                return {
                    'success': False,
                    'error': f"获取排放因子失败: {emission_factors['error']}"
                }
            
            factors = emission_factors['data']
            
            # 2. 计算原料带入排放 (E原料 = Σ（M原料 × EF原料）)
            # 将kg转换为吨，然后乘以排放因子
            # 注意：石油磺酸钙、中性油、12羟基硬脂酸、GA-034没有排放因子，排放量为0
            raw_material_emission_total_kgCO2 = (
                (_safe_float(batch.calcium_hydroxide_kg) / 1000) * factors['calcium_hydroxide_ef'] +
                (_safe_float(batch.boric_acid_kg) / 1000) * factors['boric_acid_ef'] +
                (_safe_float(batch.acetic_acid_kg) / 1000) * factors['acetic_acid_ef']
            )
            batch.raw_material_emission_total_kgCO2 = raw_material_emission_total_kgCO2
            
            # 3. 计算能耗排放 (E能耗 = M电 × e电 + M蒸汽 × e蒸汽 + M天然气 × e天然气)
            energy_emission_total_kgCO2 = (
                _safe_float(batch.electricity_kwh) * factors['electricity_ef'] +
                _safe_float(batch.steam_t) * factors['steam_ef'] +
                _safe_float(batch.natural_gas_m3) * factors['natural_gas_ef']
            )
            batch.energy_emission_total_kgCO2 = energy_emission_total_kgCO2
            
            # 4. 计算辅助材料带入排放 (E辅助材料 = 水消耗量(t) × 水排放因子)
            auxiliary_emission_total_kgCO2 = (_safe_float(batch.water_kg) / 1000) * factors['water_ef']
            batch.auxiliary_emission_total_kgCO2 = auxiliary_emission_total_kgCO2
            
            # 5. 计算运输过程排放 - 按照详细的运输数据计算
            # 5.1 原料运输排放
            raw_material_transport_emissions = (
                # 石油磺酸钙（汽运）
                ((_safe_float(batch.calcium_petroleum_sulfonate_kg) / 1000) * 
                 _safe_float(batch.calcium_petroleum_sulfonate_transport_km) * factors['road_transport_ef']) +
                
                # 中性油（海运+汽运）
                ((_safe_float(batch.neutral_oil_kg) / 1000) * 
                 _safe_float(batch.neutral_oil_transport_km) * factors['sea_road_transport_ef']) +
                
                # 氢氧化钙（汽运）
                ((_safe_float(batch.calcium_hydroxide_kg) / 1000) * 
                 _safe_float(batch.calcium_hydroxide_transport_km) * factors['road_transport_ef']) +
                
                # 硼酸（汽运）
                ((_safe_float(batch.boric_acid_kg) / 1000) * 
                 _safe_float(batch.boric_acid_transport_km) * factors['road_transport_ef']) +
                
                # 12羟基硬脂酸（汽运）
                ((_safe_float(batch.hydroxy_stearic_acid_kg) / 1000) * 
                 _safe_float(batch.hydroxy_stearic_acid_transport_km) * factors['road_transport_ef']) +
                
                # 醋酸（汽运）
                ((_safe_float(batch.acetic_acid_kg) / 1000) * 
                 _safe_float(batch.acetic_acid_transport_km) * factors['road_transport_ef']) +
                
                # GA-034（汽运）
                ((_safe_float(batch.ga_034_kg) / 1000) * 
                 _safe_float(batch.ga_034_transport_km) * factors['road_transport_ef'])
            )
            
            # 5.2 厂内运输排放（直接使用给定值或计算）
            internal_transport_emission = _safe_float(batch.internal_transport_emission_kgCO2)
            
            # 5.3 厂外产品运输排放
            external_product_transport_emission = (
                (_safe_float(batch.product_mass_kg) / 1000) * 
                _safe_float(batch.external_product_transport_km) * factors['road_transport_ef']
            )
            
            # 运输总排放
            transport_emission_total_kgCO2 = (
                raw_material_transport_emissions + 
                internal_transport_emission + 
                external_product_transport_emission
            )
            batch.transport_emission_total_kgCO2 = transport_emission_total_kgCO2
            
            # 6. 计算总排放 (E总 = E原料 + E能耗 + E辅助材料 + E运输)
            total_emission_kgCO2 = (
                raw_material_emission_total_kgCO2 + 
                energy_emission_total_kgCO2 + 
                auxiliary_emission_total_kgCO2 + 
                transport_emission_total_kgCO2
            )
            batch.total_emission_kgCO2 = total_emission_kgCO2
            
            # 7. 计算碳足迹 (碳足迹 = E总 / 产品质量(t))
            product_mass_t = _safe_float(batch.product_mass_kg) / 1000
            if product_mass_t > 0:
                carbon_footprint_kgCO2_per_t = total_emission_kgCO2 / product_mass_t
                batch.carbon_footprint_kgCO2_per_t = carbon_footprint_kgCO2_per_t
            else:
                batch.carbon_footprint_kgCO2_per_t = 0
            
            # 8. 计算详细结果分析（直接保存到batch对象中）
            batch.raw_material_stage_kgCO2 = raw_material_emission_total_kgCO2 / product_mass_t if product_mass_t > 0 else 0
            batch.energy_consumption_stage_kgCO2 = energy_emission_total_kgCO2 / product_mass_t if product_mass_t > 0 else 0
            batch.auxiliary_material_stage_kgCO2 = auxiliary_emission_total_kgCO2 / product_mass_t if product_mass_t > 0 else 0
            batch.transport_stage_kgCO2 = transport_emission_total_kgCO2 / product_mass_t if product_mass_t > 0 else 0
            
            # 9. 计算各阶段占比
            if total_emission_kgCO2 > 0:
                batch.raw_material_stage_percentage = (raw_material_emission_total_kgCO2 / total_emission_kgCO2) * 100
                batch.energy_consumption_stage_percentage = (energy_emission_total_kgCO2 / total_emission_kgCO2) * 100
                batch.auxiliary_material_stage_percentage = (auxiliary_emission_total_kgCO2 / total_emission_kgCO2) * 100
                batch.transport_stage_percentage = (transport_emission_total_kgCO2 / total_emission_kgCO2) * 100
            else:
                batch.raw_material_stage_percentage = 0
                batch.energy_consumption_stage_percentage = 0
                batch.auxiliary_material_stage_percentage = 0
                batch.transport_stage_percentage = 0
            
            # 10. 保存所有计算结果
            batch.save()

            
            return {
                'success': True,
                'data': {
                    'raw_material_emission_total_kgCO2': raw_material_emission_total_kgCO2,
                    'energy_emission_total_kgCO2': energy_emission_total_kgCO2,
                    'auxiliary_emission_total_kgCO2': auxiliary_emission_total_kgCO2,
                    'transport_emission_total_kgCO2': transport_emission_total_kgCO2,
                    'raw_material_transport_emissions': raw_material_transport_emissions,
                    'internal_transport_emission': internal_transport_emission,
                    'external_product_transport_emission': external_product_transport_emission,
                    'total_emission_kgCO2': total_emission_kgCO2,
                    'carbon_footprint_kgCO2_per_t': batch.carbon_footprint_kgCO2_per_t,
                    'product_mass_t': product_mass_t,
                    'stage_percentages': {
                        'raw_material_percentage': batch.raw_material_stage_percentage,
                        'energy_consumption_percentage': batch.energy_consumption_stage_percentage,
                        'auxiliary_material_percentage': batch.auxiliary_material_stage_percentage,
                        'transport_percentage': batch.transport_stage_percentage,
                    }
                }
            }
            
    except Exception as e:
        return {
            'success': False,
            'error': f"计算过程中发生错误: {str(e)}"
        }


def _get_lubricating_grease_emission_factors():
    """获取润滑脂排放因子"""
    try:
        # 默认排放因子值（根据文档中的表格和算法说明）
        default_factors = {
            # 产品与原料排放因子 (kgCO₂/t)
            'calcium_hydroxide_ef': 607.0,  # 氢氧化钙
            'boric_acid_ef': 4050.0,        # 硼酸
            'acetic_acid_ef': 583.0,        # 醋酸
            # 注意：中性油、石油磺酸钙、12羟基硬脂酸、GA-034未提供排放因子
            
            # 能耗工质排放因子
            'natural_gas_ef': 2.162,        # kgCO₂/m³ 天然气
            'electricity_ef': 0.9419,       # kgCO₂/kWh 电力
            'steam_ef': 271.62,             # kgCO₂/t 0.35MPa蒸汽
            
            # 辅助材料排放因子
            'water_ef': 0.62,               # kgCO₂/t 水
            
            # 运输过程排放因子
            'road_transport_ef': 0.187,     # kgCO₂/(t·km) 汽运
            'sea_road_transport_ef': 0.01,  # kgCO₂/(t·km) 海运+汽运（对应中性油的排放）
            'electric_forklift_ef': 0.9419, # kgCO₂/kWh 电叉车
        }
        
        return {
            'success': True,
            'data': default_factors
        }
            
    except Exception as e:
        return {
            'success': False,
            'error': f"获取排放因子失败: {str(e)}"
        }
